package model;


import java.util.*;

import model.NotifyPicassa;
import model.semantics.AbstractToken;
import model.semantics.OperationToken;
import model.semantics.PunctuationToken;
/**
 * Takes an expression in reverse polish notation and builds a tree.
 * 
 * @author Troy Ferrell
 *
 */
public class PicassaTreeBuilder extends AbstractTreeBuilder
{
	private AbstractParser myParser;

	// TODO: Need to update process methods to return boolean value 
	// 		 indicating whether function executed successfully

	public PicassaTreeBuilder ()
	{
		ArrayList<String> propertyList = new ArrayList<String>();
		propertyList.add("precedence");
		propertyList.add("syntax");
		propertyList.add("processor");

		myParser = new PicassaParser(propertyList);
	}

	/**
	 * Builds tree from the input string by first parsing the string and calling the tree conversion.
	 * @param infixString
	 * @return
	 */
	public AbstractToken buildTree (String infixString)
	{
		Stack<AbstractToken> RPNexpression = myParser.parseFromInfix(infixString);
		return convertToTree(RPNexpression);
	}

	/**
	 * Converts the parsed expression into a tree.
	 */
	@Override
	protected AbstractToken convertToTree(Collection<AbstractToken> parsed) {

		Stack<AbstractToken> shuntingStack = new Stack<AbstractToken>();

		for(AbstractToken token : parsed)
		{
			if( token instanceof OperationToken )
			{
				OperationToken operation = (OperationToken)token;
				for(int j = 0; j < operation.getNumArguments(); j++) 
					operation.addChild(shuntingStack.pop());

				shuntingStack.push(operation); 
			}
			else if(token instanceof PunctuationToken)
				NotifyPicassa.showError(NotifyPicassa.ARGUMENTS_ERROR);
			else
				shuntingStack.push(token);    		
		}
		return shuntingStack.pop();
	}




}
